// --------------------------------------------------------------------------------------------------------------------
// <copyright file="URDataPackages.cs" company="Microsoft Corporation">
// The MIT License (MIT)
// 
// Copyright (c) 2014, Microsoft Corporation
// 
// Permission is hereby granted, free of charge, to any person obtaining a copy
//  of this software and associated documentation files (the "Software"), to deal
//  in the Software without restriction, including without limitation the rights
//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//  copies of the Software, and to permit persons to whom the Software is
//  furnished to do so, subject to the following conditions:
// 
// The above copyright notice and this permission notice shall be included in
//  all copies or substantial portions of the Software.
// 
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//  THE SOFTWARE.
// </copyright>
// --------------------------------------------------------------------------------------------------------------------
namespace Microsoft.Robotics.Hardware.UniversalRobots
{
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using System.Runtime.InteropServices;
    using System.Text;
    using System.Threading.Tasks;

    /// <summary>
    /// Contains information needed for parsing data packages from URControl server.
    /// </summary>
    public static class URDataPackages
    {
        /// <summary>
        /// Size of package header in bytes
        /// </summary>n
        public const int HeaderSize = 5;

        /// <summary>
        /// Initializes static members of the <see cref="URDataPackages"/> class.
        /// </summary>
        static URDataPackages()
        {
            PayloadSizes = new Dictionary<PackageTypes, int>();
            PayloadSizes.Add(PackageTypes.RobotModeData, 24);
            PayloadSizes.Add(PackageTypes.JointData, 246);
            PayloadSizes.Add(PackageTypes.ToolData, 32);
            PayloadSizes.Add(PackageTypes.MasterboardData, 59);
            PayloadSizes.Add(PackageTypes.CartesianInfo, 48);
            PayloadSizes.Add(PackageTypes.ConfigurationData, 464);
            PayloadSizes.Add(PackageTypes.ForceModeData, 56);
            PayloadSizes.Add(PackageTypes.AdditionalInfo, 2);
            PayloadSizes.Add(PackageTypes.KinematicsInfo, 220);
            PayloadSizes.Add(PackageTypes.CalibrationData, 48);
        }

        /// <summary>
        /// Enumeration of the different types of packages and the 
        /// value associated with them sent by the UR arm
        /// </summary>
        public enum PackageTypes
        {
            /// <summary>
            /// Robot Mode Data
            /// </summary>
            RobotModeData = 0,

            /// <summary>
            /// Joint Data
            /// </summary>
            JointData = 1,

            /// <summary>
            /// Tool Data
            /// </summary>
            ToolData = 2,

            /// <summary>
            /// Master board Data
            /// </summary>
            MasterboardData = 3,

            /// <summary>
            /// Cartesian Information
            /// </summary>
            CartesianInfo = 4,

            /// <summary>
            /// Kinematics Information
            /// </summary>
            KinematicsInfo = 5,

            /// <summary>
            /// Configuration Data
            /// </summary>
            ConfigurationData = 6,

            /// <summary>
            /// Force Mode Data
            /// </summary>
            ForceModeData = 7,

            /// <summary>
            /// Additional Information
            /// </summary>
            AdditionalInfo = 8,

            /// <summary>
            /// Calibration data
            /// </summary>
            CalibrationData = 9
        }

        /// <summary>
        /// Possible values of robot mode
        /// </summary>
        public enum RobotModes
        {
            /// <summary>
            /// Running mode.
            /// </summary>
            Running = 0,

            /// <summary>
            /// Free drive mode.
            /// </summary>
            Freedrive = 1,

            /// <summary>
            /// Ready mode.
            /// </summary>
            Ready = 2, 

            /// <summary>
            /// Initializing mode.
            /// </summary>
            Initializing = 3,

            /// <summary>
            /// Security stopped mode.
            /// </summary>
            SecurityStopped = 4,
            
            /// <summary>
            /// Emergency stopped mode.
            /// </summary>
            EmergencyStopped = 5,

            /// <summary>
            /// Fatal error mode.
            /// </summary>
            FatalError = 6,

            /// <summary>
            /// No power mode.
            /// </summary>
            NoPower = 7,

            /// <summary>
            /// Not connected mode.
            /// </summary>
            NotConnected = 8,

            /// <summary>
            /// Shutdown mode.
            /// </summary>
            Shudown = 9, 

            /// <summary>
            /// Safeguard mode.
            /// </summary>
            SafeguardStop = 10
        }

        /// <summary>
        /// Joint modes.
        /// </summary>
        public enum JointModes
        {
            /// <summary>
            /// PartDCalibration mode
            /// </summary>
            PartDCalibration = 237,

            /// <summary>
            /// Back drive mode
            /// </summary>
            Backdrive = 238,

            /// <summary>
            /// Power off mode
            /// </summary>
            PowerOff = 239,

            /// <summary>
            /// Emergency stopped mode
            /// </summary>
            EmergencyStopped = 240,

            /// <summary>
            /// An initialization mode
            /// </summary>
            CavalInitialization = 241,

            /// <summary>
            /// Error mode
            /// </summary>
            Error = 242,
           
            /// <summary>
            /// Free drive mode
            /// </summary>
            FreeDrive = 243,

            /// <summary>
            /// Simulated mode
            /// </summary>
            Simulated = 244,

            /// <summary>
            /// Not responding mode
            /// </summary>
            NotResponding = 245,

            /// <summary>
            /// Motor initialization mode
            /// </summary>
            MotorInitialization = 246,

            /// <summary>
            /// ADC calibration mode
            /// </summary>
            AdcCalibration = 247,

            /// <summary>
            /// Dead communication mode
            /// </summary>
            DeadCommunication = 248,

            /// <summary>
            /// Boot loader mode
            /// </summary>
            Bootloader = 249,

            /// <summary>
            /// Calibration mode
            /// </summary>
            Calibration = 250,

            /// <summary>
            /// Stopped mode
            /// </summary>
            Stopped = 251,

            /// <summary>
            /// Fault mode
            /// </summary>
            Fault = 252,

            /// <summary>
            /// Running mode
            /// </summary>
            Running = 253,

            /// <summary>
            /// Initialization mode
            /// </summary>
            Initialization = 254,

            /// <summary>
            /// Idle mode
            /// </summary>
            Idle = 255
        }

        /// <summary>
        /// Gets dictionary of *payload* sizes for package types.  Does not include size of header (4 size bytes + 1 package type byte)
        /// </summary>
        public static Dictionary<PackageTypes, int> PayloadSizes { get; private set; }
    }
}
